#pragma once

namespace Tmpl {

struct MouseData;
struct KeyData;

struct InputEvent
{
	enum {KEY_PRESS, KEY_RELEASE, MOUSE_CLICK, MOUSE_RELEASE};
	int type;
	int keycode;
	int mouseButton;
};

class Mouse
{
public:
	enum Button {LMB, MMB, RMB};

	Mouse();
	~Mouse();

	bool IsInRect(int x, int y, int w, int h) const;
	bool IsDown(int button) const;
	bool IsClicked(int button) const;
	bool IsReleased(int button) const;
	bool IsDoubleClicked(int button) const;

	int GetX() const;
	int GetY() const;
	int GetXPrev() const;
	int GetYPrev() const;
	int GetScrollDelta() const; // Negative numbers mean scrolling down
	
	unsigned int GetEventCount() const;
	const InputEvent& GetEvent(unsigned int index) const;

private:
	friend class Input;
	MouseData& myData;
};

class Key
{
public:
	Key();
	~Key();

	bool IsDown(unsigned int keycode) const;
	bool IsPressed(unsigned int keycode) const;
	bool IsReleased(unsigned int keycode) const;

	unsigned int GetEventCount() const;
	const InputEvent& GetEvent(unsigned int index) const;

private:
	friend class Input;
	KeyData& myData;
};

class Input
{
public:
	Input();
	~Input();

	void BindTo(Mouse* mouse, Key* keys);

	void PressKey(unsigned int keycode);
	void ReleaseKey(unsigned int keycode);
	void ClickMb(unsigned int button);
	void ReleaseMb(unsigned int button);
	void ScrollMouseWheel(bool up);
	void SetMousePos(int x, int y);

	void SetKeysHandled();
	void SetMouseHandled();
	void Reset();

private:
	Mouse* myMouse;
	Key* myKeys;
};

enum TmplKey
{
	TK_A = 'a',
	TK_B = 'b',
	TK_C = 'c',
	TK_D = 'd',
	TK_E = 'e',
	TK_F = 'f',
	TK_G = 'g',
	TK_H = 'h',
	TK_I = 'i',
	TK_J = 'j',
	TK_K = 'k',
	TK_L = 'l',
	TK_M = 'm',
	TK_N = 'n',
	TK_O = 'o',
	TK_P = 'p',
	TK_Q = 'q',
	TK_R = 'r',
	TK_S = 's',
	TK_T = 't',
	TK_U = 'u',
	TK_V = 'v',
	TK_W = 'w',
	TK_X = 'x',
	TK_Y = 'y',
	TK_Z = 'z',

	TK_0 = '0',
	TK_1 = '1',
	TK_2 = '2',
	TK_3 = '3',
	TK_4 = '4',
	TK_5 = '5',
	TK_6 = '6',
	TK_7 = '7',
	TK_8 = '8',
	TK_9 = '9',

	TK_ESCAPE =	256,
	TK_CTRL,
	TK_CTRL_L,
	TK_CTRL_R,
	TK_SHIFT,
	TK_SHIFT_L,
	TK_SHIFT_R,
	TK_ALT,
	TK_ALT_L,
	TK_ALT_R,
	TK_SYSTEM,
	TK_SYSTEM_L,
	TK_SYSTEM_R,
	TK_MENU,
	TK_BRACKET_L,	// [
	TK_BRACKET_R,	// ]
	TK_SEMICOLON,	// ;
	TK_COMMA,		// ,
	TK_PERIOD,		// .
	TK_QUOTE,		// '
	TK_SLASH,		// /
	TK_BACKSLASH,	// \ 
	TK_TILDE,		// ~
	TK_EQUAL,		// =
	TK_DASH,		// -
	TK_SPACE,
	TK_RETURN,		
	TK_BACKSPACE,
	TK_TAB,
	TK_PAGE_UP,
	TK_PAGE_DOWN,
	TK_END,
	TK_HOME,
	TK_INSERT,
	TK_DELETE,
	TK_ADD,			// +
	TK_SUBTRACT,	// -
	TK_MULTIPLY,	// *
	TK_DIVIDE,		// /
	TK_LEFT,		// Left arrow
	TK_RIGHT,		// Right arrow
	TK_UP,			// Up arrow
	TK_DOWN,		// Down arrow

	TK_NUMPAD0,
	TK_NUMPAD1,
	TK_NUMPAD2,
	TK_NUMPAD3,
	TK_NUMPAD4,
	TK_NUMPAD5,
	TK_NUMPAD6,
	TK_NUMPAD7,
	TK_NUMPAD8,
	TK_NUMPAD9,

	TK_F1,
	TK_F2,
	TK_F3,
	TK_F4,
	TK_F5,
	TK_F6,
	TK_F7,
	TK_F8,
	TK_F9,
	TK_F10,
	TK_F11,
	TK_F12,
	TK_F13,
	TK_F14,
	TK_F15,

	TK_PAUSE,
	TK_ANYKEY,

	TK_KEY_COUNT
};

extern Key key;
extern Mouse mouse;
extern Input input;

}; // namespace Tmpl